package org.jin.samples.log;

import java.util.Arrays;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

@Component
@Aspect
public class LogAspect {
	/**
	 * 配置在web包下所有的类在调用之前都会被拦截 
	 */
	@Pointcut("execution(* org.jin.samples.web.*.*(..))")
	public void allMethod(){}
	
	@Pointcut("execution(* org.jin.samples.web.SubjectController.saveSubject(..))")
	public void saveSubject(){}
	
	@Pointcut("execution(* org.jin.samples.web.SubjectController.updataSubject(..))")
	public void updataSubject(){}
	
	@After("allMethod()")
	public void afterLog(JoinPoint point){
		System.out.println("afterlog-----最终通知");
		System.out.println("afterlog-----目标方法："+point.getSignature().getDeclaringTypeName()+"."+point.getSignature().getName());
		System.out.println("afterlog-----参数为："+Arrays.toString(point.getArgs()));
		System.out.println("afterlog-----被织入的目标对象为："+point.getTarget());
	}
	
	@Before("allMethod()")
	public void beforeLog(){
		System.out.println("beforeLog------");
	}
	
	
	@AfterReturning(value="allMethod()", returning = "returnValue")
	public void afterReturningLog(JoinPoint point, Object returnValue){
		System.out.println("afterReturningLog------返回值后通知");
		System.out.println("afterReturningLog------目标方法为："+
				point.getSignature().getDeclaringTypeName()+"."
				+point.getSignature().getName());
		System.out.println("afterReturningLog------参数为："+
				Arrays.toString(point.getArgs()));
		System.out.println("afterReturningLog------返回值："+returnValue);
	}
	
	@AfterThrowing(throwing="ex", value="allMethod()")
	public void afterThrowingLog(Throwable ex){
		System.out.println("afterThrowingLog--------进入循环通知");
		System.out.println("afterThrowingLog--------异常信息："+ex.getMessage());
	}
	
	@Around("allMethod()")
	public Object doAround(ProceedingJoinPoint pjp)throws Throwable{
		System.out.println("Around--------进入环绕通知");
		Object obj = pjp.proceed();
		System.out.println("Around--------结束方法调用");
		return obj;
	}
	
	
}















